/*******************************************************************************
 * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
 * @file     transport.c
 * @author   UartTFT Application Team
 * @version  V0.0.1
 * @date     2023-01-01
 * @brief
 ********************************************************************************/

#include "transport.h"
#include "delay.h"
#include "data.h"
#include "w25qxx.h"
#include "w25n01.h"
#include "tftlcd.h"
#include "module_select.h"
#include "edma_drv.h"

void LT268_Flash_Read_Model(uint32_t Addr)        
{
	if(Flash_Type!=2)   // NorFlash 
	{
	
		Flash_SS_RESET;     
		exFlash_SPI_ReadWriteByte(W25X_READ);   	
		if(Flash_Type)exFlash_SPI_ReadWriteByte((uint8_t)(Addr>>24));    					
		exFlash_SPI_ReadWriteByte((uint8_t)((Addr)>>16)); 
		exFlash_SPI_ReadWriteByte((uint8_t)((Addr)>>8));
		exFlash_SPI_ReadWriteByte((uint8_t)Addr);
	}
	else  				//NandFlash 
	{
		unsigned short page,remainder;
		remainder = Addr%2048;
		page = (Addr/2048);
		
		//W25N01GV_ContinuousRead_Mode(); //ContinuousRead_Mode ( BUF=0 )
		LT_W25N01GV_PageDataRead(page);	  //page_addr, read from colum 0

		Flash_SS_RESET; 
		#if 0
		exFlash_SPI_ReadWriteByte(W25N01GV_ReadData);
		NorFlash_DMA_Read(DMA_txbuf1, DMA_rxbuf2,remainder+3);     //Dummy clock + Dummy data 
		NorFlash_DMA_Wait();											  
		#else
		exFlash_SPI_ReadWriteByte(W25N01GV_READ_FAST);
		NorFlash_DMA_Read(DMA_txbuf1, DMA_rxbuf2,remainder+4);     //Dummy clock + Dummy data
		NorFlash_DMA_Wait();											  
		#endif
	}   	
}

extern uint8_t lt_screen_dir;

void LT_UI_changeaddr(uint32_t *addr)
{
//	if(lt_screen_dir==0 || lt_screen_dir==2)
//	{
//		*addr += 0; 
//	}
//	else if(lt_screen_dir==1 || lt_screen_dir==3)
//	{
//		*addr += 0x02FA4BE6;
//	}
//	else if(lt_screen_dir==2)
//	{
//		*addr += 30123832;
//	}
//	else if(lt_screen_dir==3)
//	{
//		*addr += 0;
//	}
//	*addr += 0x002F20DC;
}

void LT_ReadFlash_UI(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
	
	LT_UI_changeaddr(&ReadAddr);
	
	// LT_ReadFlash(pBuffer,ReadAddr,NumByteToRead);
	if(Flash_Type!=2)
	{
		W25QXX_STD_Read(pBuffer,ReadAddr,NumByteToRead);
	}
	else
	{
		LT_W25N01GV_ReadData(pBuffer,ReadAddr,NumByteToRead);
	}
	DelayUS(1); // wav need
}

void LT_ReadFlash_DMA_UI(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
	LT_UI_changeaddr(&ReadAddr);
	
	uint32_t dma_len = DMA_LEN3;

	LT268_Flash_Read_Model(ReadAddr);   			//
	
	if(NumByteToRead <= dma_len)	dma_len=NumByteToRead;
	for(;;)
	{

		NorFlash_DMA_Read(pBuffer,pBuffer,dma_len);
		NorFlash_DMA_Wait();
//		DelayUS(1);                       // wav need

		if(NumByteToRead==dma_len)break;
		else
		{
			pBuffer+=dma_len;
			ReadAddr+=dma_len;
			NumByteToRead-=dma_len;			 
			if(NumByteToRead>DMA_LEN3) dma_len=DMA_LEN3;
			else dma_len=NumByteToRead; 	  
		}
	}
	Flash_SS_SET;

	DelayUS(1); // wav need
}

/********************************************************************************
* Function Name	: LT_ReadFlash
* Description  	: Read data from external FLASH.
* Input        	: - *pBuffer: buffer for read data
				  - ReadAddr: Address to start reading
				  - NumByteToRead: Number of bytes to read
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_ReadFlash(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
	
	if(Flash_Type!=2)
	{
		W25QXX_STD_Read(pBuffer,ReadAddr,NumByteToRead);
	}
	else
	{
		LT_W25N01GV_ReadData(pBuffer,ReadAddr,NumByteToRead);
	}
	DelayUS(1); // wav need
}

/********************************************************************************
* Function Name	: LT_ReadFlash_DMA
* Description  	: Read data from external FLASH.
* Input        	: - *pBuffer: buffer for read data
				  - ReadAddr: Address to start reading
				  - NumByteToRead: Number of bytes to read
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_ReadFlash_DMA(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
	uint32_t dma_len = DMA_LEN3;

	LT268_Flash_Read_Model(ReadAddr);   			//
	
	if(NumByteToRead <= dma_len)	dma_len=NumByteToRead;
	for(;;)
	{

		NorFlash_DMA_Read(pBuffer,pBuffer,dma_len);
		NorFlash_DMA_Wait();
//		DelayUS(1);                       // wav need

		if(NumByteToRead==dma_len)break;
		else
		{
			pBuffer+=dma_len;
			ReadAddr+=dma_len;
			NumByteToRead-=dma_len;			 
			if(NumByteToRead>DMA_LEN3) dma_len=DMA_LEN3;
			else dma_len=NumByteToRead; 	  
		}
	}
	Flash_SS_SET;

	DelayUS(1); // wav need
}

/********************************************************************************
* Function Name	: TFT_Data_Tran
* Description  	: Write array data to TFT continuously.(Mainly for picture drawing)
* Input        	: - *Tx_Addr: data buffer(RGB565,little endian)
				  - length: Number of bytes to write(even number)
* Output       	: None
* Return       	: None
*********************************************************************************/
void TFT_Data_Tran(uint8_t *Tx_Addr, uint32_t length)
{
#if (LT_TFT_PORT == 0)

	if (length == 0)return;
	uint32_t i;
	uint16_t *Data = (uint16_t *)Tx_Addr;

	for (i = 0; i < length / 2; i++)
	{
		Data[i] = ((Data[i] >> 8) | (Data[i] << 8));
	}
	
	#if (LT_TFTSPI_DMA == 1)
	LCD_SPI_WriteData_DMA(Tx_Addr, length);
	#elif (LT_TFTSPI_DMA == 2)
	LCD_SPI_WriteData_EDMA(Tx_Addr,length,0);    
	#endif
#endif

#if (LT_TFT_PORT == 1 || LT_TFT_PORT == 2)
	uint32_t m = 0;

	for (m = 1; m <= length / 2; m++)
	{
#if (LT_TFT_PORT == 1)
		LCD_DATA_WRITE_L(Tx_Addr[2 * m - 1]);
		LCD_WR_RESET; 			  
		LCD_WR_SET;	
		LCD_DATA_WRITE_L(Tx_Addr[2 * m - 2]);
		LCD_WR_RESET; 			  
		LCD_WR_SET;	
#endif
#if (LT_TFT_PORT == 2)
		LCD_DATA_WRITE_H(Tx_Addr[2 * m - 1]);
		LCD_DATA_WRITE_L(Tx_Addr[2 * m - 2]);
		LCD_WR_RESET; 			  
		LCD_WR_SET;	
#endif
	}
#endif
}


/********************************************************************************
* Function Name	: TFT_Data_Tran
* Description  	: Write the same color to TFT continuously.(Mainly for 2D drawing)
* Input        	: - *Tx_Addr: data buffer(RGB565,big endian)
				  - length: Number of bytes to write
* Output       	: None
* Return       	: None
*********************************************************************************/
void TFT_Data_Tran2(uint16_t Tx_Addr, uint32_t length)
{
#if (LT_TFT_PORT == 0)
	#if (LT_TFTSPI_DMA == 0)
		for (uint32_t i = 0; i < length; i++)
		{
			LCD_SPI_ReadWriteByte(Tx_Addr >> 8);
			//		__ASM("nop");	__ASM("nop"); __ASM("nop"); __ASM("nop");
			LCD_SPI_ReadWriteByte(Tx_Addr);
			//		__ASM("nop");	__ASM("nop"); __ASM("nop"); __ASM("nop");
		}
	#elif (LT_TFTSPI_DMA == 1)
		for (uint32_t i = 0; i < length; i++)
		{
			LCD_SPI_ReadWriteByte(Tx_Addr >> 8);
			//		__ASM("nop");	__ASM("nop"); __ASM("nop"); __ASM("nop");
			LCD_SPI_ReadWriteByte(Tx_Addr);
			//		__ASM("nop");	__ASM("nop"); __ASM("nop"); __ASM("nop");
		}
	#elif (LT_TFTSPI_DMA == 2)
		//	SPI_MasterOnlySendDataByEDMA(SPI3,(uint32_t)DMA_SPI_txbuf1,length);
		uint8_t buff[4];
		buff[0] = Tx_Addr>>8;
		buff[1] = Tx_Addr;
		buff[2] = Tx_Addr>>8;
		buff[3] = Tx_Addr;
		LCD_SPI_WriteData_EDMA(buff,length*2,1);
	#endif
#endif

#if (LT_TFT_PORT == 1 || LT_TFT_PORT == 2)
	uint32_t m = 0;

	for (m = 0; m < length; m++)
	{
#if (LT_TFT_PORT == 1)
		LCD_DATA_WRITE_L(Tx_Addr >> 8);
		LCD_WR_RESET; 			  
		LCD_WR_SET;	
		LCD_DATA_WRITE_L(Tx_Addr);
		LCD_WR_RESET; 			  
		LCD_WR_SET;	
#endif
#if (LT_TFT_PORT == 2)
		LCD_DATA_WRITE_H(Tx_Addr >> 8);
		LCD_DATA_WRITE_L(Tx_Addr);
		LCD_WR_RESET; 			  
		LCD_WR_SET;	
#endif
	}
#endif
}



//----------------------------------------------------------------------------------
